package com.jzo2o.customer.service.impl;

import cn.hutool.core.bean.BeanException;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.api.customer.dto.response.AddressBookResDTO;
import com.jzo2o.api.publics.MapApi;
import com.jzo2o.api.publics.dto.response.LocationResDTO;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.common.utils.NumberUtils;
import com.jzo2o.common.utils.StringUtils;
import com.jzo2o.customer.mapper.AddressBookMapper;
import com.jzo2o.customer.model.domain.AddressBook;
import com.jzo2o.customer.model.dto.request.AddressBookPageQueryReqDTO;
import com.jzo2o.customer.model.dto.request.AddressBookUpsertReqDTO;
import com.jzo2o.customer.service.IAddressBookService;
import com.jzo2o.mvc.utils.UserContext;
import com.jzo2o.mysql.utils.PageUtils;
import org.checkerframework.checker.signature.qual.FullyQualifiedName;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 地址薄 服务实现类
 * </p>
 *
 * @author itcast
 * @since 2023-07-06
 */
@Service
public class AddressBookServiceImpl extends ServiceImpl<AddressBookMapper, AddressBook> implements IAddressBookService {

    @Autowired
    private AddressBookMapper addressBookMapper;

    @Autowired
    private MapApi mapApi;


    @Override
    public List<AddressBookResDTO> getByUserIdAndCity(Long userId, String city) {

        List<AddressBook> addressBooks = lambdaQuery()
                .eq(AddressBook::getUserId, userId)
                .eq(AddressBook::getCity, city)
                .list();
        if (CollUtils.isEmpty(addressBooks)) {
            return new ArrayList<>();
        }
        return BeanUtils.copyToList(addressBooks, AddressBookResDTO.class);
    }

    @Override
    public AddressBookResDTO getDefaultAddress() {
        //获取当前登录用户id
        AddressBook addressBook = this.lambdaQuery()
                .eq(AddressBook::getUserId, UserContext.currentUserId())
                .eq(AddressBook::getIsDefault, 1)
                .one();

        System.out.println(UserContext.currentUserId());
        if (ObjectUtil.isEmpty(addressBook)) {
            return null;
        }

        AddressBookResDTO addressBookResDTO = BeanUtils.copyBean(addressBook, AddressBookResDTO.class);


        return addressBookResDTO;

    }

    //添加新地址

    @Override
    public void saveAddressBook(AddressBookUpsertReqDTO dto) {
        /*
        * 1. 默认地址一个用户只能有一个，如果设置新地址为默认地址，则需要取消旧的默认地址
          2. 如果前端没有传递经纬度，则需要根据传递的详细地址调用高德地图获取经纬度（相关接口已经提供）
        * */


        //默认地址
        //1.首先获取用户id,根据当前用户id查找地址对象
        Long userId = UserContext.currentUserId();
        List<AddressBook> addressBooks = addressBookMapper.selectList(Wrappers.<AddressBook>lambdaQuery()
                .eq(AddressBook::getUserId, userId));
        if (CollUtils.isEmpty(addressBooks)) {
            //添加新地址并且设置默认地址
            dto.setIsDefault(1);
            addressBook(dto);
        }
        //判断传递过来的地址是否是默认地址1
        if (dto.getIsDefault() == 1) {
            //取消集合中的默认地址,将默认地址设置为0
            addressBooks.forEach(e -> {
                if (e.getIsDefault() == 1) {
                    e.setIsDefault(0);
                    //更新地址信息
                    addressBookMapper.updateById(e);
                }
            });
            //添加新地址
            addressBook(dto);
        }

    }

    /**
     * 获取地址簿列表
     *
     * @param dto
     * @return
     */
    @Override
    public PageResult<AddressBookResDTO> getPage(AddressBookPageQueryReqDTO dto) {

        //设置分页参数
        Page<AddressBook> page = PageUtils.parsePageQuery(dto, AddressBook.class);

        //设置查询条件
        LambdaQueryWrapper<AddressBook> wrapper =
                Wrappers.<AddressBook>lambdaQuery().eq(AddressBook::getUserId, UserContext.currentUserId());

        //分页查询
        Page<AddressBook> serveTypePage = baseMapper.selectPage(page, wrapper);

        return PageUtils.toPage(serveTypePage, AddressBookResDTO.class);
    }

    /**
     * 地址簿详情
     * @param id
     * @return
     */

    @Override
    public AddressBookResDTO detailAddress(Long id) {
        AddressBook addressBook = addressBookMapper.selectById(id);
        return BeanUtils.copyBean(addressBook, AddressBookResDTO.class);
    }

    /**
     * 修改地址
     * @param id
     * @param dto
     */
    @Override
    public void editAddress(Long id, AddressBookUpsertReqDTO dto) {
        //根据地址id查询地址
        AddressBook addressBook = new AddressBook();

        //拷贝属性
        BeanUtils.copyProperties(dto, addressBook);
        String location = dto.getLocation();
        //设置相关属性
        addressBook.setId(id);
        addressBook.setUserId(UserContext.currentUserId());
        //如果经纬度为空
        if(location==null)
        {
            //根据地址查询经纬度
             location = mapApi.getLocationByAddress(dto.getProvince()+dto.getCity()+dto.getCounty()+dto.getAddress()).getLocation();
        }

        //拆分经纬度
        String[] split = location.split(",");
        addressBook.setLon(Double.valueOf(split[0]));
        addressBook.setLat(Double.valueOf(split[1]));


        addressBook.setUpdateTime(LocalDateTime.now());

        //更新地址
        addressBookMapper.updateById(addressBook);
    }

    /**
     * 设置默认地址
     * @param flag
     * @param id
     */
    @Override
    public void setDefaultAddress(Integer flag, Long id) {
        //根据当前登录用户id查询地址
        List<AddressBook> list = addressBookMapper.selectList(Wrappers.<AddressBook>lambdaQuery()
                .eq(AddressBook::getUserId, UserContext.currentUserId()));

        if(CollUtils.isEmpty(list))
        {
            throw new BeanException("获取用户地址失败");
        }

        //将集合中的默认地址取消
        list.forEach(e -> {
            if(e.getIsDefault()==1)
            {
                e.setIsDefault(0);
            }
            updateById(e);
        });

        //设置新的默认地址
        updateById(addressBookMapper.selectById(id).setIsDefault(flag));

    }


    private void addressBook(AddressBookUpsertReqDTO dto) {
        AddressBook addressBook = BeanUtils.copyBean(dto, AddressBook.class);
        addressBook.setUserId(UserContext.currentUserId());
        //判断是否有经纬度
        String location = dto.getLocation();
        if (location == null || location.isEmpty()) {
            //调用高德地图获取经纬度
            location = mapApi.getLocationByAddress(dto.getProvince()+dto.getCity()+dto.getCounty()+dto.getAddress()).getLocation();
        }

        //将经纬度进行一个拆分
        String[] list = location.split(",");
        addressBook.setLon(Double.valueOf(list[0]));
        addressBook.setLat(Double.valueOf(list[1]));
        addressBook.setIsDeleted(0);
        //添加地址
        addressBookMapper.insert(addressBook);
        //todo 自动填充创建时间等待填充字段
    }
}
